
//websocket用例的搭建
//想要在规定参数外传入自己想要的参数，实现相应的操作，可以使用bind 进行参数绑定，记得按照规定进行预留参数
//此时生成的可调用对象里面依然是规定的参数，同时也传入了自己想要使用的参数

#include<iostream>
#include<string>
#include<websocketpp/server.hpp>
#include<websocketpp/config/asio_no_tls.hpp>

typedef websocketpp::server<websocketpp::config::asio> wsserver_t;

void http_callback(wsserver_t *srv , websocketpp::connection_hdl hdl)
{
    //给客户端返回一个hello word页面

    //获取http请求的关键要素
    wsserver_t::connection_ptr conn=srv->get_con_from_hdl(hdl);

    //通过连接对象获取http请求内容
    std::cout<<"body"<<conn->get_request_body()<<std::endl;//打印请求正文

    //获得请求信息的对象
    websocketpp::http::parser::request req=conn->get_request();
    std::cout<<"method"<<req.get_method()<<std::endl;//获取请求方法
    std::cout<<"uri"<<req.get_uri()<<std::endl;//获取资源路径

    //响应一个简单的html页面
    //std::string body="<html><body><h1>Hello World</h1></body></html>";
    //conn->set_body(body);//设置http响应正文
    conn->set_body(conn->get_request_body());
    conn->append_header("Content-Type","text/html");//设置http响应头部字段
    conn->set_status(websocketpp::http::status_code::ok);//设置响应状态码

}

void wsopen_callback(wsserver_t *srv , websocketpp::connection_hdl hdl)
{
     std::cout << "websocket握手成功！！\n";
}

void wsclose_callback(wsserver_t *srv , websocketpp::connection_hdl hdl)
{
    std::cout << "websocket连接断开！！\n";
}

void wsmsg_callback(wsserver_t *srv , websocketpp::connection_hdl hdl,wsserver_t::message_ptr msg)
{
    //取出通信连接对象
    wsserver_t::connection_ptr conn=srv->get_con_from_hdl(hdl);

    //获取客户端向我们发送的数据
    std::cout<<"wsmag:"<<msg->get_payload()<<std::endl;

    //要对接收到的数据进行响应
    std::string rsp="client say: "+msg->get_payload();
    conn->send(rsp,websocketpp::frame::opcode::text);//发送文本类型对象 
}

int main()
{
    //1.实例化server对象
    wsserver_t wssrv;
    //2.设置日志等级
    wssrv.set_access_channels(websocketpp::log::alevel::none);
    //3.初始化asio调度器
    wssrv.init_asio();
    wssrv.set_reuse_addr(true);
    //4.设置回调函数
    wssrv.set_http_handler(std::bind(http_callback,&wssrv,std::placeholders::_1));
    wssrv.set_open_handler(std::bind(wsopen_callback,&wssrv,std::placeholders::_1));
    wssrv.set_close_handler(std::bind(wsclose_callback,&wssrv,std::placeholders::_1));
    wssrv.set_message_handler(std::bind(wsmsg_callback,&wssrv,std::placeholders::_1,std::placeholders::_2));

    //5.设置监听窗口
    wssrv.listen(8085);

    //6.开始获取新连接
    wssrv.start_accept();
    //7.启动服务器
    wssrv.run();

    return 0;
}

//去云服务器把对应的端口添加到策略组也就是防火墙当中，要开通这个端口才能进行访问